#
# Sha3
#
SHA3 = 0x20
#
# Environment Information
#
ADDRESS = 0x30
BALANCE = 0x31
ORIGIN = 0x32
CALLER = 0x33
CALLVALUE = 0x34
CALLDATALOAD = 0x35
CALLDATASIZE = 0x36
CALLDATACOPY = 0x37
CODESIZE = 0x38
CODECOPY = 0x39
GASPRICE = 0x3A
EXTCODESIZE = 0x3B
EXTCODECOPY = 0x3C
RETURNDATASIZE = 0x3D
RETURNDATACOPY = 0x3E
EXTCODEHASH = 0x3F
SHA3 指令用於計算給定資料的 SHA3 雜湊(hash),通常使用 Keccak-256 演算法。這個雜湊可以用來識別資料,通常用於加密和安全相關的操作。
def sha3(self):
data_start = self.evm.stack.pop()
data_length = self.evm.stack.pop()
data = self.evm.memory[data_start:data_start + data_length]
result = keccak256(data)
self.evm.stack.append(result)
在實現 SHA3 指令時,我們首先從堆疊中取出資料的起始位置和長度。然後,從記憶體中提取相應的資料,並對其進行 SHA3 雜湊運算。最後,將計算結果推送回堆疊。
請注意,為了實現 SHA3 指令,你需要使用適當的 SHA3(Keccak-256)演算法。這裡,我們假設有一個名為 keccak256
的函數,用於計算給定資料的 SHA3 雜湊。
假設有資料 "hello, world!"
要計算 SHA3 雜湊,可以使用 SHA3 指令:
sha3(data_start_position, data_length)
這將計算 "hello, world!"
的 SHA3 雜湊並將結果推送到堆疊上。
環境資訊指令允許合約在執行過程中獲取與執行環境相關的資訊。
ADDRESS 指令:將當前合約的地址推送到堆疊。
def address(self):
self.evm.stack.append(self.evm.address)
BALANCE 指令:將指定地址的餘額推送到堆疊。
def balance(self):
address = self.evm.stack.pop()
# 假設有一個函數 get_balance(address) 可以取得地址的餘額
balance = get_balance(address)
self.evm.stack.append(balance)
ORIGIN 指令:將交易的原始發送者地址推送到堆疊。
def origin(self):
self.evm.stack.append(self.evm.origin)
CALLER 指令:將調用合約的地址推送到堆疊。
def caller(self):
self.evm.stack.append(self.evm.caller)
CALLVALUE 指令:將交易的值(以 wei 為單位)推送到堆疊。
def callvalue(self):
self.evm.stack.append(self.evm.callvalue)
CALLDATALOAD 指令:從調用數據中加載一個字。
def calldataload(self):
position = self.evm.stack.pop()
data_word = self.evm.calldata[position:position+32]
self.evm.stack.append(data_word)
CALLDATASIZE 指令:獲取調用數據的大小。
def calldatasize(self):
size = len(self.evm.calldata)
self.evm.stack.append(size)
CALLDATACOPY 指令:將調用數據複製到記憶體中。
def calldatacopy(self):
mem_start = self.evm.stack.pop()
data_start = self.evm.stack.pop()
length = self.evm.stack.pop()
data = self.evm.calldata[data_start:data_start+length]
self.evm.memory[mem_start:mem_start+length] = data
CODESIZE 指令:獲取合約代碼的大小。
def codesize(self):
size = len(self.evm.code)
self.evm.stack.append(size)
CODECOPY 指令:將合約代碼複製到記憶體中。
def codecopy(self):
mem_start = self.evm.stack.pop()
code_start = self.evm.stack.pop()
length = self.evm.stack.pop()
code_data = self.evm.code[code_start:code_start+length]
self.evm.memory[mem_start:mem_start+length] = code_data
GASPRICE 指令:獲取當前交易的 gas 價格。
def gasprice(self):
self.evm.stack.append(self.evm.gasprice)
EXTCODESIZE 指令:獲取指定地址的合約代碼大小。
def extcodesize(self):
address = self.evm.stack.pop()
size = len(get_code_at_address(address))
self.evm.stack.append(size)
EXTCODECOPY 指令:將指定地址的合約代碼複製到記憶體中。
def extcodecopy(self):
address = self.evm.stack.pop()
mem_start = self.evm.stack.pop()
code_start = self.evm.stack.pop()
length = self.evm.stack.pop()
code_data = get_code_at_address(address)[code_start:code_start+length]
self.evm.memory[mem_start:mem_start+length] = code_data
RETURNDATASIZE 指令:獲取返回數據的大小。
def returndatasize(self):
size = len(self.evm.returndata)
self.evm.stack.append(size)
RETURNDATACOPY 指令:將返回數據複製到記憶體中。
def returndatacopy(self):
mem_start = self.evm.stack.pop()
data_start = self.evm.stack.pop()
length = self.evm.stack.pop()
data = self.evm.returndata[data_start:data_start+length]
self.evm.memory[mem_start:mem_start+length] = data
EXTCODEHASH 指令:獲取指定地址的合約代碼的 Keccak-256 雜湊。
def extcodehash(self):
address = self.evm.stack.pop()
code = get_code_at_address(address)
code_hash = keccak256(code)
self.evm.stack.append(code_hash)
這些指令提供了合約在執行過程中所需的環境資訊。請注意,某些函數(如 get_code_at_address
和 keccak256
)在此示例中被假設為已存在,但在實際應用中可能需要實現或從其他庫中導入。